package orm

import (
	"fmt"
	"gorm.io/gorm/schema"
	"strings"
)

type Query struct {
	TableName       string
	SelectColumns   []string
	DistinctColumns []string
	QueryBuilder    strings.Builder
	QueryArgs       []interface{}
	Page            int
	Size            int
}

func NewQuery() *Query {
	return &Query{}
}

func (q *Query) WithTableName(table string) *Query {
	q.TableName = table
	return q
}

func (q *Query) Table(table schema.Tabler) *Query {
	q.TableName = table.TableName()
	return q
}

func (q *Query) Eq(column interface{}, val interface{}) *Query {
	q.addCond(column, val, Eq)
	return q
}

func (q *Query) Ne(column interface{}, val interface{}) *Query {
	q.addCond(column, val, Ne)
	return q
}

func (q *Query) Gt(column interface{}, val interface{}) *Query {
	q.addCond(column, val, Gt)
	return q
}

func (q *Query) Ge(column interface{}, val interface{}) *Query {
	q.addCond(column, val, Ge)
	return q
}

func (q *Query) Lt(column interface{}, val interface{}) *Query {
	q.addCond(column, val, Lt)
	return q
}

func (q *Query) Le(column interface{}, val interface{}) *Query {
	q.addCond(column, val, Le)
	return q
}

func (q *Query) Like(column interface{}, val string) *Query {
	q.addCond(column, "%"+val+"%", Like)
	return q
}

func (q *Query) LikeLeft(column interface{}, val interface{}) *Query {
	return q
}

func (q *Query) LikeRight(column interface{}, val interface{}) *Query {
	return q
}

func (q *Query) IsNull(column interface{}, val interface{}) *Query {
	return q
}

func (q *Query) IsNotNull(column interface{}, val interface{}) *Query {
	return q
}

func (q *Query) In(column interface{}, val interface{}) *Query {
	q.addCond(column, val, In)
	return q
}

func (q *Query) NotIn(column interface{}, val interface{}) *Query {
	return q
}

func (q *Query) Between(column interface{}, val interface{}) *Query {
	return q
}

func (q *Query) And() *Query {
	q.QueryBuilder.WriteString(And)
	q.QueryBuilder.WriteString(" ")
	return q
}

func (q *Query) Or(column interface{}, val interface{}) *Query {
	return q
}

func (q *Query) Group(column interface{}, val interface{}) *Query {
	return q
}

func (q *Query) OrderByAsc(column interface{}, val interface{}) *Query {
	return q
}

func (q *Query) OrderByDesc(column interface{}, val interface{}) *Query {
	return q
}

func (q *Query) Having(column interface{}, val interface{}) *Query {
	return q
}

func (q *Query) addCond(column interface{}, val interface{}, condType string) {
	q.addAndIfNeed()
	q.QueryBuilder.WriteString(fmt.Sprintf(" %s %s ? ", column, condType))
	q.QueryArgs = append(q.QueryArgs, val)
}

func (q *Query) addAndIfNeed() {
	if q.QueryBuilder.Len() > 0 {
		q.QueryBuilder.WriteString(And)
		q.QueryBuilder.WriteString(" ")
	}
}
